<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:ci="http://apache.org/cocoon/include/1.0" xmlns:cu="http://apache.org/cocoon/counit"
  version="1.0">

  <!-- 
    Prepare the xslt transformation in the testcases where this is required (with 
    the xslt element). This stylesheet places a verbose cinclude command on the 
    location where the output should be placed.
    The cinclude command should perform a POST to an "external" URL (which in fact
    is an internal pipeline). This is required for proper error handling, see below.
    In the POST parameters the input XML is included if it is an inline XML fragment, 
    otherwise a uri is passed. If it is included, it will be read with the streamgenerator.
    
    Authors: Jan Willem Boer <janwillem@jwenr.nl>
  -->

  <xsl:include href="cook-cinclude.xsl"/>

  <!-- type of the transformation, should be one of 'xslt' 'stx' -->
  <xsl:param name="type"/>

  <!-- add a type attribute to the testcase -->
  <xsl:template match="cu:testcase">
    <!-- copy the testcase element -->
    <xsl:choose>
      <xsl:when test="*[local-name()=$type]">
        <!-- a testcase of our type, process it -->
        <xsl:copy>
          <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
      </xsl:when>
      <xsl:otherwise>
        <!-- 
          Another boring testcase, copy to the result tree.
          Don't process-templates, because a nested transformation, 
          which should be called recursively in a next step, may contain 
          a transformation of our type. That one should not be processed now.
        -->
        <xsl:copy-of select="."/>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:template>

  <!-- skip the cu:generate element (a document element to hold the transformation
  in case of a generated stylesheet) -->
  <xsl:template match="cu:generate">
    <xsl:choose>
      <xsl:when test="*[local-name()=$type]">
        <xsl:apply-templates/>
      </xsl:when>
      <xsl:otherwise>
        <!-- we have nothing to do with this one. copy it to the result tree -->
        <xsl:copy-of select="."/>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:template>

  <!-- copy ci elements, because these are processed already -->
  <xsl:template match="ci:*">
    <xsl:copy-of select="."/>
  </xsl:template>
  
  
  <!-- eat the cu:input element of transformations for this type. The
    element will be included in the cook-cinclude template directly. -->
  <xsl:template match="cu:input"/>

  <!-- 
    match the stx or xslt element and make up the cinclude. 
  -->
  <xsl:template match="cu:*">
 <xsl:choose>
   <xsl:when test="local-name()=$type">
     <!-- transformation type found -->
     <xsl:call-template name="cook-cinclude">
       <!-- (this will also result in a call to . mode=local-settings) -->
       <xsl:with-param name="pipeline-to-call">
         <xsl:text>transform-by-ss/</xsl:text>
         <xsl:value-of select="$type"/>
       </xsl:with-param>
     </xsl:call-template>
   </xsl:when>
   <xsl:otherwise>
     <!-- this is any other element like cu:testsuite or cu:expect, copy it -->
     <xsl:copy>
       <xsl:apply-templates select="@*|node()"/>
     </xsl:copy>
   </xsl:otherwise>
 </xsl:choose>   
  </xsl:template>

  <!-- 
    include a parameter for the xslt/stx transformation in the cinclude instruction 
    The context node is cu:xslt or cu:stx 
  -->
  <xsl:template match="*" mode="local-settings">
    <xsl:param name="base"/>
    <xsl:param name="testsuite-dir"/>
    <xsl:param name="counit-url"/>

    <xsl:choose>
      <xsl:when test="@src">
        <ci:parameter>
          <ci:name>counit-ss-method</ci:name>
          <ci:value>uri</ci:value>
        </ci:parameter>
        <ci:parameter>
          <ci:name>counit-ss</ci:name>
          <ci:value>
            <xsl:value-of select="concat($base, @src)"/>
          </ci:value>
        </ci:parameter>
      </xsl:when>
      <xsl:otherwise>
        <ci:parameter>
          <ci:name>counit-ss-method</ci:name>
          <ci:value>generated</ci:value>
        </ci:parameter>
        <ci:parameter>
          <ci:name>counit-ss</ci:name>
          <ci:value>
            <!-- 
              the xslt or stx element holds an input element plus a transformation
              element to generate the stylesheet with. At least it should.
            -->
            <xsl:variable name="id" select="ancestor::*[@id][1]/@id"/>
            <xsl:if test="count(cu:*) != 2">
              <xsl:message terminate="yes"><xsl:value-of select="$id"/>: a generated stylesheet
                should have an input element and a transformation element.</xsl:message>
            </xsl:if>
            <cu:generate base="{$base}" testsuite-dir="{$testsuite-dir}" counit-url="{$counit-url}"
              id="{$id}">
              <xsl:copy-of select="cu:*"/>
            </cu:generate>
          </ci:value>
        </ci:parameter>
      </xsl:otherwise>
    </xsl:choose>
    <!-- include stylesheet parameters -->
    <xsl:apply-templates select="cu:parameter" mode="include-parameters"/>
  </xsl:template>


  <!-- include the parameters for the transformation -->
  <xsl:template match="cu:parameter" mode="include-parameters">
    <ci:parameter>
      <ci:name>
        <xsl:value-of select="@name"/>
      </ci:name>
      <ci:value>
        <xsl:value-of select="@value"/>
      </ci:value>
    </ci:parameter>
  </xsl:template>

</xsl:stylesheet>
